package display
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import mx.core.FlexGlobals;
	import mx.core.FlexSprite;
	import mx.graphics.IStroke;
	
	import util.DisplayUtil;
	
	/**
	 * FreeLine下面最少有一条line,可支持点的拖拽，新线的生成。
	 * 墙壁由FreeLine组成
	 * 
	 */
	public class FreeLine extends FlexSprite
	{
		private var _lines:Array;
		
		private var _stroke:IStroke;
		
		private var anchor:Sprite;
		
		//0:什么都没有;1,进入;2,选中achor; 3,拖动achor;
		private var _state:int;
		
		/**鼠标在上面移动*/
		private var activeOverLine:Line;
		
		/**鼠标点击后anchor global位置 */
		private var anchorStartPoint:Point;
		
		private var anchorStartLocation:Point;
		
		private var freeMovePoint:Point;
		
		private var freeMoveStartPoint:Point;
		
		/**
		 * 一个freeline可以被拆分，拆分后，Wall需要
		 * 把这个被拆分的splitedLine也放在wall里面
		 */
		private var _splitedLine:FreeLine;
		
		override public function FreeLine()
		{
			super();
			this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			this.addEventListener(MouseEvent.ROLL_OUT, onMouseOut);
			this.addEventListener(Event.ADDED_TO_STAGE, onStageReady);
		}
			

		private function onStageReady(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, onStageReady);
			stageInit();
		}
		
		private function stageInit():void
		{
			this.stage.addEventListener(MouseEvent.MOUSE_UP, onStageUp, false, 0, true);
		}
		
		public function validate():void
		{
			if(lines != null)
			{
				draw();
			}
		}
		
		public function refresh():void
		{
			var length:int = lines.length;
			for(var i:int = 0; i < length; i++)
			{
				Line(lines[i]).validate();
			}
		}
		
		protected function draw():void
		{
			DisplayUtil.removeAll(this, [anchor]);
			var length:int = lines.length;
			for(var i:int = 0; i < length; i++)
			{
				this.addChild(lines[i] as DisplayObject);
			}
		}
		
		private function get state():int
		{
			return _state;
		}

		private function set state(v:int):void
		{
			_state = v;
			switch(v)
			{
				case 0:
				    if(anchor && this.contains(anchor))
				    {
				    	this.removeChild(anchor);
				    	anchor.removeEventListener(MouseEvent.MOUSE_DOWN, onAnchorDown);
				    }	
				    if(this.stage)
				    {
				    	this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMoveAnchor);
				    }	    
				    this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				    this.addEventListener(MouseEvent.ROLL_OUT, onMouseOut);		    
				    break;
				case 1:
				   if(anchor == null)
				   {
				   	    var weight:Number = activeOverLine.stroke.weight;
				   	    anchor = new Sprite();
				   	    anchor.graphics.beginFill(0x0000ff);
				   	    anchor.graphics.drawCircle(0, 0, weight + 3);
				   	    anchor.graphics.endFill(); 
				   }
				   if(!this.contains(anchor))
				   {
				   	  this.addChild(anchor);
				   }
				   anchor.addEventListener(MouseEvent.MOUSE_DOWN, onAnchorDown);
				   break;
				case 2:
				  this.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				  this.removeEventListener(MouseEvent.ROLL_OUT, onMouseOut);
				  this.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMoveAnchor);
				  //拆分line
				  var point1:Point = activeOverLine.pointOne;
				  //如果距离小于3，则认为选中了Line 的起始点.
				  var distance:Number = Point.distance(point1, anchorStartLocation);
				  trace("point one distance: " + distance);
				  if(distance <= 3)
				  {
				  	 freeMovePoint = point1; 
				  }
				  else
				  {
				  	  distance = Point.distance(activeOverLine.pointTwo, anchorStartLocation);
					  trace("point two distance: " + distance);
					  if(distance <= 3)
					  {
					  	 freeMovePoint = activeOverLine.pointTwo; 
					  }
					  else
					  {
					  	  //拆分activeOverLine
					  	  freeMovePoint = new Point(this.mouseX, this.mouseY);
					  	  var newLine:Line = new Line([point1, freeMovePoint], activeOverLine.stroke);
					  	  var newLine2:Line = new Line([freeMovePoint, activeOverLine.pointTwo], activeOverLine.stroke);
					  	  lines.splice(lines.indexOf(activeOverLine), 1);
					  	  lines.push(newLine);
					  	  lines.push(newLine2);
					  	  this.lines = lines;
					  	  this.dispatchEvent(new Event("freeLineEdited", true));	  	  
					  }
				  }  
				  freeMoveStartPoint = freeMovePoint.clone();
				  break;  
			}
			
		}
		
		/**
		 * 移动Anchor,线跟着跑
		 */
		private function onMoveAnchor(event:MouseEvent):void
		{
			var xDelta:Number = (event.stageX - anchorStartPoint.x);
			var yDelta:Number = (event.stageY - anchorStartPoint.y);
			
			anchor.x = anchorStartLocation.x + xDelta;
			anchor.y = anchorStartLocation.y + yDelta;
			
			trace("x delta: " + xDelta + " ax: " + anchor.x);
			trace("y delta: " + yDelta + " ay: " + anchor.y);
			
			freeMovePoint.x = freeMoveStartPoint.x + xDelta;
			freeMovePoint.y = freeMoveStartPoint.y + yDelta;
			this.dispatchEvent(new Event("needRefresh", true));
		}
		
		private function onMouseDown(event:Event):void
		{
			var line:Line  = event.target as Line;
			if(line != null)
			{
			}
		}
		
		
		
		private function onAnchorDown(event:MouseEvent):void
		{
			anchorStartPoint = new Point(event.stageX, event.stageY);
			anchorStartLocation = new Point(anchor.x, anchor.y);
			state = 2;
		}
		
		//选择了别的地方的时候，取消选择
		private function onStageUp(event:MouseEvent):void
		{
			state = 0;
		}
		
		private function onMouseMove(event:Event):void
		{
			var app:Object = FlexGlobals.topLevelApplication;
			if(!app || app.mode != HouseArch.MODE_EDIT_LINE)
			{
				return;
			}
			var line:Line  = event.target as Line;
			if(line != null)
			{
				activeOverLine = line;
				if(state == 0)
				{
					state = 1;
				}
				anchor.x = this.mouseX;
				anchor.y = this.mouseY;
			}
		}
		
		private function onMouseUp(event:Event):void
		{
			state = 0;
		}
		
		private function onMouseOut(event:Event):void
		{
			state = 0;
		}
		
		/**
		 * 拆分freeLine,如果是在该地方拆分，则返回新生成的freeline，
		 * 并且freeline中第一个Line的pointOne就是拆分点
		 * 否则返回方位
		 * lt:表示上方或者左边
		 * rb:表示下方或者右边
		 * @see display.Line#pointOne
		 */
		public function split(position:Number, direction:String):Object
		{
			var onLine:Line;
			var splitPoint:Point;
			var leftLines:Array = [];
			var rightLines:Array = [];
			for(var i:int = lines.length - 1; i >= 0; i--)
			{
				var result:Object = Line(lines[i]).split(position, direction);
				if(result is Point)
				{
					onLine = Line(lines[i]);
					splitPoint = result as Point;
					continue;
				}
				//把lines分成两大阵营,1个阵营仍然呆在freeline中，另一个则放在splitedLine中
				if(result == "lt")
				{
					leftLines.push(lines[i]);
				}
				else
				{
					rightLines.push(lines[i]);
				}
			}
			if(splitPoint == null)
			{
				return leftLines.length > 0 ? "lt" : "rb";
			}		
			var newLine:Line = new Line([splitPoint, onLine.pointTwo], onLine.stroke);
			onLine.pointTwo = splitPoint;
			
			leftLines.push(onLine);
			this.lines = leftLines;
			splitedLine = new FreeLine();
			rightLines.unshift(newLine);
			splitedLine.lines = rightLines;
			this.dispatchEvent(new Event("freeLineSplited", true));
			return splitedLine;
		}
		

		public function get leftTopPoint():Point
		{
			var p:Point = new Point(int.MAX_VALUE, int.MAX_VALUE);
			for(var i:int = lines.length - 1; i >= 0; i--)
			{
				var line:Line = lines[i] as Line;
				if(line.pointOne.x < p.x || line.pointOne.y < p.y)
				{
					p = line.pointOne;
				}
			}
			return p;
		}
		
		public function get rightBottomPoint():Point
		{
			var p:Point = new Point(0, 0);
			for(var i:int = lines.length - 1; i >= 0; i--)
			{
				var line:Line = lines[i] as Line;
				if(line.pointTwo.x > p.x || line.pointTwo.y > p.y)
				{
					p = line.pointTwo;
				}
			}
			return p;
		}
		
		public function scale(oldSize:Point, newSize:Point):void
		{
			for(var i:int = lines.length - 1; i >= 0; i--)
			{
				Line(lines[i]).scale(oldSize, newSize);
			}
		}

		public function get lines():Array
		{
			return _lines;
		}

		public function set lines(v:Array):void
		{
			_lines = v;
			validate();
		}

		public function get stroke():IStroke
		{
			return _stroke;
		}

		public function set stroke(v:IStroke):void
		{
			_stroke = v;
			for(var i:int = lines.length - 1; i >= 0; i--)
			{
				Line(lines[i]).stroke = v;
			}
		}

		public function get splitedLine():FreeLine
		{
			return _splitedLine;
		}

		public function set splitedLine(v:FreeLine):void
		{
			_splitedLine = v;
		}


	}
}